package com.ray.finance.api;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ray.base.check.CustomerCheck;
import com.ray.base.service.BaseCustomerService;
import com.ray.base.table.entity.BaseCustomer;
import com.ray.business.check.BusinessCheck;
import com.ray.business.check.OrderCheck;
import com.ray.business.service.ProdPurchaseService;
import com.ray.business.service.compose.BusinessService;
import com.ray.business.service.compose.PurcahseService;
import com.ray.business.service.compose.SaleService;
import com.ray.business.table.entity.ProdBusiness;
import com.ray.business.table.entity.ProdOrder;
import com.ray.business.table.params.business.BusinessCreateParams;
import com.ray.business.table.vo.BusinessVO;
import com.ray.business.table.vo.PurchaseVO;
import com.ray.common.SysMsgCodeConstant;
import com.ray.finance.builder.BillBuilder;
import com.ray.finance.builder.BillVOBuilder;
import com.ray.finance.check.BillCheck;
import com.ray.finance.enums.BillSourceEnum;
import com.ray.finance.enums.BillStatusEnum;
import com.ray.finance.service.FinaBillAdjustService;
import com.ray.finance.service.FinaBillService;
import com.ray.finance.table.dto.BillQueryDTO;
import com.ray.finance.table.entity.FinaBill;
import com.ray.finance.table.params.BillAdjuestQueryParams;
import com.ray.finance.table.params.BillCreateParams;
import com.ray.finance.table.params.BillQueryParams;
import com.ray.finance.table.vo.BillVO;
import com.ray.magicBlock.BlockDispatch;
import com.ray.system.builder.CommonPageBuilder;
import com.ray.woodencreate.beans.LoginUser;
import com.ray.woodencreate.page.CommonPage;
import com.ray.woodencreate.result.MsgCodeConstant;
import com.ray.woodencreate.result.Result;
import com.ray.woodencreate.result.ResultFactory;
import com.ray.woodencreate.util.Assert;
import com.ray.woodencreate.util.LogInUserUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author bo shen
 * @Description: 对账单
 * @Class: BillApi
 * @Package com.ray.finance.api
 * @date 2020/6/15 15:35
 * @company <p>Ray快速开发平台</p>
 * @updateRecord time(修改时间)  author(修改人)   desc(修改内容)
 */
@Slf4j
@Service
public class BillApi {

    @Autowired
    private FinaBillService finaBillService;
    @Autowired
    private FinaBillAdjustService finaBillAdjustService;
    @Autowired
    private BaseCustomerService baseCustomerService;
    @Autowired
    private BillAdjustApi billAdjustApi;
    @Autowired
    private BusinessService businessService;
    @Autowired
    private BlockDispatch<BillCreateParams, LoginUser, String> createDispatch;
    @Autowired
    private BlockDispatch<FinaBill, LoginUser, String> cancelDispatch;
    @Autowired
    private PurcahseService purcahseService;
    @Autowired
    private SaleService saleService;

    /**
     * 查询订单列表信息 分页  非删除的
     *
     * @param queryParams
     * @return
     */
    public Result<IPage<BillVO>> pageBillss(CommonPage<BillQueryParams, Page<BillVO>> queryParams) {
        Assert.notNull(queryParams, SysMsgCodeConstant.Error.ERR10000001);
        //当前登录对象
        LoginUser loginUser = LogInUserUtil.get();
        Map<String, BaseCustomer> baseCustomerMap = new HashMap<>();
        CommonPageBuilder<BillQueryDTO, FinaBill> commonPageBuilder = new CommonPageBuilder<>(BillQueryDTO.class);
        commonPageBuilder.appendEntity(queryParams.getEntity()).appendQuery(queryParams.getQuery()).appendPage(queryParams.getPage());
        IPage<FinaBill> page = finaBillService.page(commonPageBuilder.bulid(), loginUser);
        List<FinaBill> orders = page.getRecords();
        //结果对象
        IPage<BillVO> pageList = new Page<>();
        pageList.setTotal(page.getTotal());
        pageList.setCurrent(page.getCurrent());
        pageList.setSize(page.getSize());
        //查询到结果 数据转换
        if (ObjectUtil.isNotNull(orders)) {
            pageList.setRecords(orders.stream().map(sysBill -> {
                //查询客信息
                BaseCustomer baseCustomer = baseCustomerMap.get(sysBill.getCustomerCode());
                if (ObjectUtil.isEmpty(baseCustomer)) {
                    baseCustomer = baseCustomerService.queryCustomerByCustomerCode(sysBill.getCustomerCode(), loginUser);
                    baseCustomerMap.put(sysBill.getCustomerCode(), baseCustomer);
                }
                BillVOBuilder orderVOBuilder = new BillVOBuilder();
                orderVOBuilder.append(sysBill).append(baseCustomer);
                return orderVOBuilder.bulid();
            }).collect(Collectors.toList()));
        } else {
            pageList.setRecords(new ArrayList<>());
        }
        return ResultFactory.createSuccessResult(MsgCodeConstant.Success.SUC00000002, pageList);
    }


    /**
     * 创建加工业务入库单
     *
     * @return
     */
    @Transactional
    public Result<String> createBusinessBill(BillCreateParams createParams, BillSourceEnum billSourceEnum) {
        //当前登录对象
        LoginUser loginUser = LogInUserUtil.get();
        String billNo = createDispatch.dispatch("createBill", billSourceEnum.getValue(), createParams, loginUser);
        return ResultFactory.createSuccessResult(MsgCodeConstant.Success.SUC00000002, billNo);
    }

    /**
     * 取消
     *
     * @return
     */
    @Transactional
    public Result<String> cancelBill(String billNo) {
        Assert.hasLength(billNo, "参数[billNo]不能为空");
        //当前登录对象
        LoginUser loginUser = LogInUserUtil.get();
        FinaBill finaBill = finaBillService.queryBillByBillNo(billNo, loginUser);
        new BillCheck(finaBill).checkNull("对账单不存在").checkCanCancel("对账单不能取消");
        //取消业务单
        cancelDispatch.dispatch("cancelBill", finaBill.getBillSource(), finaBill, loginUser);
        finaBillAdjustService.deleteByBillNo(billNo, loginUser);
        return ResultFactory.createSuccessResult(MsgCodeConstant.Success.SUC00000002, billNo);
    }

    /**
     * 删除
     *
     * @return
     */
    @Transactional
    public Result<String> deleteBill(String billNo) {
        Assert.hasLength(billNo, "参数[billNo]不能为空");
        //当前登录对象
        LoginUser loginUser = LogInUserUtil.get();
        FinaBill finaBill = finaBillService.queryBillByBillNo(billNo, loginUser);
        new BillCheck(finaBill).checkNull("对账单不存在").checkCanDelete("对账单不能删除");
        BillBuilder billBuilder = new BillBuilder();
        billBuilder.appendEdit(loginUser).appendCode(finaBill.getBillNo()).delete();
        finaBillService.edit(billBuilder.bulid(), loginUser);
        //取消业务单
        cancelDispatch.dispatch("cancelBill", finaBill.getBillSource(), finaBill, loginUser);
        finaBillAdjustService.deleteByBillNo(billNo, loginUser);
        return ResultFactory.createSuccessResult(MsgCodeConstant.Success.SUC00000002, billNo);
    }


    /**
     * 完成
     *
     * @return
     */
    @Transactional
    public Result<String> finishBill(String billNo) {
        Assert.hasLength(billNo, "参数[billNo]不能为空");
        //当前登录对象
        LoginUser loginUser = LogInUserUtil.get();
        FinaBill finaBill = finaBillService.queryBillByBillNo(billNo, loginUser);
        new BillCheck(finaBill).checkNull("对账单不存在").checkCanFinish("对账单不能完成");
        BillBuilder billBuilder = new BillBuilder();
        billBuilder.appendEdit(loginUser).appendCode(finaBill.getBillNo()).appendTime(LocalDateTime.now()).appendOrderStatus(BillStatusEnum.FINISH.getValue());
        finaBillService.edit(billBuilder.bulid(), loginUser);
        return ResultFactory.createSuccessResult(MsgCodeConstant.Success.SUC00000002, billNo);
    }


    /**
     * 删除
     *
     * @return
     */
    @Transactional
    public Result<String> passBill(String billNo) {
        Assert.hasLength(billNo, "参数[billNo]不能为空");
        //当前登录对象
        LoginUser loginUser = LogInUserUtil.get();
        FinaBill finaBill = finaBillService.queryBillByBillNo(billNo, loginUser);
        new BillCheck(finaBill).checkNull("对账单不存在").checkCanCheck("对账单已审核");
        BillBuilder billBuilder = new BillBuilder();
        billBuilder.appendEdit(loginUser).appendCode(finaBill.getBillNo()).appendOrderStatus(BillStatusEnum.PASS.getValue());
        finaBillService.edit(billBuilder.bulid(), loginUser);
        return ResultFactory.createSuccessResult(MsgCodeConstant.Success.SUC00000002, billNo);
    }

    /**
     * 对账单详情
     *
     * @param billNo
     * @return
     */
    public Result<BillVO> viewBill(String billNo) {
        Assert.hasLength(billNo, "参数[billNo]不能为空");
        //当前登录对象
        LoginUser loginUser = LogInUserUtil.get();
        FinaBill finaBill = finaBillService.queryBillByBillNo(billNo, loginUser);
        new BillCheck(finaBill).checkNull("对账单不存在");
        //查询客信息
        BaseCustomer baseCustomer = baseCustomerService.queryCustomerByCustomerCode(finaBill.getCustomerCode(), loginUser);
        BillVOBuilder orderVOBuilder = new BillVOBuilder();
        orderVOBuilder.append(finaBill).append(baseCustomer);
        //对账详情
        if (StrUtil.equals(finaBill.getBillSource(), BillSourceEnum.BUSINESS.getValue())) {
            List<BusinessVO> businessVOS = businessService.queryBusinessByBIllNo(billNo, baseCustomer.getCustomerName(), loginUser);
            orderVOBuilder.appendBusiness(businessVOS);
        }
        //对账详情
        if (StrUtil.equals(finaBill.getBillSource(), BillSourceEnum.PURCHASE.getValue())) {
            List<BusinessVO> businessVOS = purcahseService.queryPurchaseByBIllNo(billNo, baseCustomer.getCustomerName(), loginUser);
            orderVOBuilder.appendBusiness(businessVOS);
        }

        //对账详情
        if (StrUtil.equals(finaBill.getBillSource(), BillSourceEnum.SALE.getValue())) {
            List<BusinessVO> businessVOS = saleService.querySaleByBIllNo(billNo, baseCustomer.getCustomerName(), loginUser);
            orderVOBuilder.appendBusiness(businessVOS);
        }
        //调整详情
        BillAdjuestQueryParams queryParams = new BillAdjuestQueryParams();
        queryParams.setBillNo(finaBill.getBillNo());
        orderVOBuilder.append(billAdjustApi.queryAdjusts(queryParams).getData());
        return ResultFactory.createSuccessResult(MsgCodeConstant.Success.SUC00000002, orderVOBuilder.bulid());

    }
}
